package ar.edu.caece.pl.asem.model.impl.treeelements;

import ar.edu.caece.pl.asem.temp.TemporalGenerator;

public class DivisionNat extends AbstractElement {

	private int tempResultDivNat; //propio para producto de enteros, se usa para guardar el resultado de un producto temporal.
	
	public DivisionNat (){
		this.label = "DIVISION_NATURAL";
	}
	
	public int getTemp() {
		return tempResultDivNat;
	}
	
	public void setTemp(int temp) {
		this.tempResultDivNat = temp;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof DivisionNat))
			return false;
		DivisionNat other = (DivisionNat) obj;
		if (label == null) {
			if (other.label != null)
				return false;
		} else if (!label.equals(other.label))
			return false;
		return true;
	}
	
	@Override
	public void generateASMCode() {
		StringBuffer sb = new StringBuffer(); 
		String term = null;	
		String divisorName;

		AbstractElement dividendo = this.getChildren().get(0);
		AbstractElement divisor = this.getChildren().get(1);
		dividendo.parent = this;
		dividendo.generateASMCode();
		sb.append(dividendo.code);
		
		this.place = TemporalGenerator.getInstance().getActualTemporal();
		
		if (this.parent instanceof SumaInt || this.parent instanceof RestaInt || this.parent instanceof SumaNat || this.parent instanceof RestaNat) {
			TemporalGenerator.getInstance().releaseTemporal();
			term = TAB + "mov " + TemporalGenerator.getInstance().getActualTemporal() + ",ax" + ENTER;
		}
		
		if(divisor instanceof Parametro){
			divisorName = "[bp+"+ ((Parametro) divisor).getMemoryInStack() +']';
		}else{
			if(divisor instanceof NumeroNat){
				divisorName = String.valueOf(((NumeroNat) divisor).getValue());
			}else if((divisor instanceof Variable && ((Variable) divisor).getMemoryInStack() != 0)){
				divisorName = "[bp-"+ ((Variable) divisor).getMemoryInStack() +']';
			}else{
				divisorName = divisor.getEnvName() + "_" + divisor.getName();
			}
		}
		
		sb.append(getNaturalDiv(this.place, this.place, divisorName));
	
		if (term != null) {
			sb.append(term);
		}		
		
		this.code = sb.toString();
	
	}
	
	private String getNaturalDiv (String label, String op1, String op2) {
        StringBuffer sb = new StringBuffer();
		sb.append(TAB + "mov ax, " + op2 + ENTER);
        sb.append(TAB + "mov bx, ax" + ENTER);
        sb.append(TAB + "mov dx, 0" + ENTER);
        sb.append(TAB + "mov ax, " + op1 + ENTER);
        sb.append(TAB + "div bx" + ENTER);
        sb.append(TAB + "mov " + label + ",ax" + ENTER);
        return sb.toString();
	}

}
